// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using ValidationAspects;
using ValidationAspects.Core;
using ValidationAspects.Sdk;

namespace WpfStateValidation
{
	internal class DataErrorInfoImpl : IDataErrorInfo
	{
		private readonly object _instance;

		public DataErrorInfoImpl(object instance)
		{
			Enforce.IsNotNull(instance, "instance");
			_instance = instance;
		}

		#region Implementation of IDataErrorInfo
		public string this[string columnName]
		{
			get
			{
				Type type = _instance.GetType();
				PropertyInfo property = type.GetProperty(columnName);
				if (property == null)
					throw new ArgumentException(string.Format("Property [name:{0}] is unknown for [type:{1}]", columnName, type));

				var validator = property.ResolveValidator();
				if (validator != null)
				{
					object value = property.GetValue(_instance, null);
					MethodInfo method = property.GetSetMethod(true);
					ValidationContext context = new ValidationContext(_instance, type, property, method, method.GetParameters()[0], new[] {value});

					try
					{
						validator.Invoke(value, context);
					}
					catch (ValidationException e)
					{
						e.SetContext(context);
						return e.Messages.OrderBy(s => s).Aggregate((a, m) => a + Environment.NewLine + m);
					}
				}

				return null;
			}
		}

		public string Error
		{
			get { return null; }
		}
		#endregion
	}
}